﻿using MvcApplication.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcApplication.Common
{
    public class PermissionAuthrizationAttribute : AuthorizeAttribute
    {
        const string AuthPermissionKey = "_application_key";

        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            var attrs = filterContext.ActionDescriptor.GetCustomAttributes(typeof(PermissionAttribute), false);
            if (attrs != null && attrs.Length > 0)
            {
                var permission = attrs[0] as PermissionAttribute;
                if (!filterContext.RouteData.Values.ContainsKey(AuthPermissionKey))
                    filterContext.RouteData.Values.Add(AuthPermissionKey, permission);
            }

            base.OnAuthorization(filterContext);
        }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            var routeData = ((MvcHandler)httpContext.Handler).RequestContext.RouteData;
            PermissionAttribute permission = null;
            if (routeData.Values.ContainsKey(AuthPermissionKey))
            {
                permission = (PermissionAttribute)routeData.Values[AuthPermissionKey];
            }

            if (permission == null) return true;
            if (!AppSettings.IsVirrtualHosting)
            {
                if (!httpContext.User.Identity.IsAuthenticated) return false;
            }


            var user = UserSession.User;
            if (user == null) return false;
            if (user.IsAdmin) return true;

            switch (permission.PermissionType)
            {
                case Entity.PermissionType.访问:
                    return user.Menus.Any(t => t.CanView && permission.Menu == t.Menu);
                case Entity.PermissionType.编辑:
                    return user.Menus.Any(t => t.CanEdit && permission.Menu == t.Menu);
                case Entity.PermissionType.删除:
                    return user.Menus.Any(t => t.CanDelete && permission.Menu == t.Menu);

                default: throw new NotSupportedException("不支持的全选方式：" + permission.PermissionType.ToString());
            }
        }
    }
}